﻿using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using vm.Aspects.Threading;

namespace vm.Aspects.Tests.Threading
{
    [TestClass]
    public class WriterSlimLockTest
    {
        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void TestFailedConstructor()
        {
            new WriterSlimSync(null);
        }

        [TestMethod]
        public void TestConstructor()
        {
            var lck = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
            using(new WriterSlimSync(lck))
            {
                Assert.IsFalse(lck.IsReadLockHeld);
                Assert.IsFalse(lck.IsUpgradeableReadLockHeld);
                Assert.IsTrue(lck.IsWriteLockHeld);
            }

            Assert.IsFalse(lck.IsReadLockHeld);
            Assert.IsFalse(lck.IsUpgradeableReadLockHeld);
            Assert.IsFalse(lck.IsWriteLockHeld);
        }

        [TestMethod]
        public void TestIsDisposed()
        {
            var lck = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
            var sync = new WriterSlimSync(lck);

            try
            {
                Assert.IsFalse(sync.IsDisposed);
                Assert.IsFalse(lck.IsReadLockHeld);
                Assert.IsFalse(lck.IsUpgradeableReadLockHeld);
                Assert.IsTrue(lck.IsWriteLockHeld);
            }
            finally
            {
                Assert.IsFalse(sync.IsDisposed);
                sync.Dispose();
                Assert.IsTrue(sync.IsDisposed);
            }

            Assert.IsFalse(lck.IsReadLockHeld);
            Assert.IsFalse(lck.IsUpgradeableReadLockHeld);
            Assert.IsFalse(lck.IsWriteLockHeld);
        }
    }
}
